package org.budo.dubbo.protocol.http.cipher;

import com.alibaba.dubbo.rpc.Invocation;
import lombok.Setter;
import org.budo.dubbo.protocol.http.Consts;
import org.budo.dubbo.protocol.http.invocation.BudoDubboRpcInvocation;
import org.springframework.util.Assert;

/**
 * @author limingwei
 */
@Setter
public abstract class AbstractCipherService implements CipherService {
    private String appKey;

    private String appSecret;

    protected abstract String cipher(String requestBody, String appSecret);

    protected abstract String decipher(String requestBody, String appSecret);

    @Override
    public BudoDubboRpcInvocation cipher(BudoDubboRpcInvocation budoInvocation) {
        String appKey = this.getAppKey(budoInvocation);
        Assert.hasText(appKey, "#24 AbstractCipherService.appKey is null, this=" + this);

        String appSecret = this.getAppSecret(appKey);
        Assert.hasText(appSecret, "#27 AbstractCipherService.appSecret is null, this=" + this);

        String requestBody = budoInvocation.getRequestBody();
        String cipher = this.cipher(requestBody, appSecret);
        budoInvocation.setRequestBody(cipher);

        budoInvocation.setAttachment(Consts.HeaderKey.AppKey_2, appKey);

        return budoInvocation;
    }

    @Override
    public BudoDubboRpcInvocation decipher(BudoDubboRpcInvocation budoInvocation) {
        String appKey = this.getAppKey(budoInvocation);
        Assert.hasText(appKey, "#41 appKey is null, this=" + this + ", invocation=" + budoInvocation);

        String appSecret = this.getAppSecret(appKey);
        Assert.hasText(appSecret, "#44 appSecret is null, this=" + this + ", invocation=" + budoInvocation);

        String requestBody = budoInvocation.getRequestBody();
        String decipher = this.decipher(requestBody, appSecret);
        budoInvocation.setRequestBody(decipher);
        return budoInvocation;
    }

    private String getAppSecret(String appKey) {
        return this.appSecret;
    }

    private String getAppKey(Invocation invocation) {
        return this.appKey;
    }
}
